using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Aurora.AI.Common.Models;
using Microsoft.AspNetCore.Http;

namespace Aurora.AI.Common.Extensions;

public static class HttpContextExtension
{
    public static async ValueTask WriteOpenAiResultAsync(this HttpContext context, string content, string model,
        string systemFingerprint, string id, string type = "chat")
    {
        var openAiResult = new OpenAIResult
        {
            id = id,
            _object = "chat.completion.chunk",
            created = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
            model = model,
            system_fingerprint = systemFingerprint,
            type = type,
            choices =
            [
                new Choice
                {
                    index = 0,
                    message = new MessageDto
                    {
                        content = content,
                        role = "assistant"
                    },
                    finish_reason = null
                }
            ]
        };

        await context.Response.WriteAsync("data: " + JsonSerializer.Serialize(openAiResult, new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        }) + "\n\n", Encoding.UTF8);
        await context.Response.Body.FlushAsync();
    }


    public static async ValueTask WriteOpenAiResultAsync(this HttpContext context, OpenAIMixMessage content,
        string model,
        string systemFingerprint, string id, string type = "chat", List<string> sourceFiles = null)
    {
        var openAiResult = new OpenAIResult
        {
            id = id,
            _object = "chat.completion.chunk",
            created = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
            model = model,
            system_fingerprint = systemFingerprint,
            type = type,
            choices =
            [
                new Choice
                {
                    index = 0,
                    message = new MessageDto
                    {
                        content = content.content,
                        role = "assistant"
                    },
                    finish_reason = null,
                    web_search = content.web_search
                }
            ],
            sourceFiles = sourceFiles
        };

        await context.Response.WriteAsync("data: " + JsonSerializer.Serialize(openAiResult, new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        }) + "\n\n", Encoding.UTF8);
        await context.Response.Body.FlushAsync();
    }

    public static async Task WriteEndAsync(this HttpContext context, string content)
    {
        await context.Response.WriteAsync("data: " + JsonSerializer.Serialize(new OpenAIResult
        {
            id = Guid.NewGuid().ToString("N"),
            _object = "chat.completion.chunk",
            created = DateTimeOffset.Now.ToUnixTimeSeconds(),
            model = string.Empty,
            system_fingerprint = Guid.NewGuid().ToString("N"),
            choices =
            [
                new Choice
                {
                    index = 0,
                    message = new MessageDto
                    {
                        content = content,
                        role = "assistant"
                    },
                    delta = new MessageDto
                    {
                        content = content,
                        role = "assistant"
                    },
                    finish_reason = null
                }
            ]
        }, new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        }) + "\n\n", Encoding.UTF8);
        await context.Response.Body.FlushAsync();
        await context.WriteEndAsync();
    }

    /// <summary>
    /// 输出结束
    /// </summary>
    /// <param name="context"></param>
    public static async Task WriteEndAsync(this HttpContext context)
    {
        await context.Response.WriteAsync("data: [DONE]\n\n");
        await context.Response.Body.FlushAsync();
    }

    /// <summary>
    /// 写入错误的响应信息
    /// </summary>
    /// <param name="context"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public static async ValueTask WriteErrorAsync(this HttpContext context, string message)
    {
        var error = new OpenAIResult()
        {
            id = Guid.NewGuid().ToString("N"),
            _object = "chat.completion.chunk",
            created = DateTimeOffset.Now.ToUnixTimeSeconds(),
            model = string.Empty,
            system_fingerprint = Guid.NewGuid().ToString("N"),
            choices =
            [
                new Choice
                {
                    index = 0,
                    message = new MessageDto
                    {
                        content = message,
                        role = "assistant"
                    },
                    delta = new MessageDto
                    {
                        content = message,
                        role = "assistant"
                    },
                    finish_reason = "error",
                }
            ]
        };
        await context.Response.WriteAsync("data: " + JsonSerializer.Serialize(error) + "\n\n", Encoding.UTF8);
        await context.Response.Body.FlushAsync();
        await Task.Delay(100);
        await context.WriteEndAsync();
    }
}